﻿using OpenCvSharp;
using System;
using System.IO;

namespace AssistCore
{
    public class ImageCore
    {
        public static System.Drawing.Point MatchTemplate(byte[] source, byte[] target, out double min, out double max, bool showResult = false, int matchType = 1)
        {
            var sourceMat = Mat.FromImageData(source);
            var tmplMat = Mat.FromImageData(target);
            Mat resultMat = new Mat();
            var method = (TemplateMatchModes)matchType;
            Cv2.MatchTemplate(sourceMat, tmplMat, resultMat, method);

            Point minLoc, maxLoc = new Point();
            Cv2.MinMaxLoc(resultMat, out min, out max, out minLoc, out maxLoc);

            var matchLoc = new Point();
            if (method == TemplateMatchModes.SqDiff || method == TemplateMatchModes.SqDiffNormed)
            {
                matchLoc = minLoc;
            }
            else
            {
                matchLoc = maxLoc;
            }
            Point p = new Point(matchLoc.X + tmplMat.Cols, matchLoc.Y + tmplMat.Rows);
            if (showResult)
            {
                Cv2.Rectangle(sourceMat, matchLoc, p, new Scalar(0, 0, 255));
                Cv2.ImShow("result", sourceMat);
            }
            return new System.Drawing.Point(p.X, p.Y);
        }
        public static System.Drawing.Point? MatchTemplate(string source, string target, int matchType = 1, int similar = 1)
        {
            var sourceByte = File.ReadAllBytes(source);
            var targetByte = File.ReadAllBytes(target);
            return ImageCore.MatchTemplate(sourceByte, targetByte, matchType, similar);
        }
        public static System.Drawing.Point? MatchTemplate(byte[] sourceByte, byte[] targetByte, int matchType = 1, int similar = 1)
        {
            if (similar > 3 || similar < 1)
            {
                throw new ArgumentNullException("相似度只能在1-3之间");
            }
            if (!Enum.IsDefined(typeof(TemplateMatchModes), matchType))
            {
                throw new Exception("对比方式不正确");
            }
            double[] sqDiffValue = new double[] { 0, 0.04, 0.03, 0.02 };
            double[] ccoeffValue = new double[] { 0, 0.85, 0.9, 0.95 };
            double[] ccorrValue = new double[] { 0, 0.85, 0.9, 0.95 };

            double min, max;
            System.Drawing.Point p = MatchTemplate(sourceByte, targetByte, out min, out max, false, matchType);
            Console.WriteLine("min:{0},max:{1}", min, max);
            switch (matchType)
            {
                case (int)TemplateMatchModes.SqDiffNormed:
                    {
                        if (min <= sqDiffValue[similar])
                        {
                            return p;
                        }
                        break;
                    }
                case (int)TemplateMatchModes.CCoeffNormed:
                    {
                        if (max >= ccoeffValue[similar])
                        {
                            return p;
                        }
                        break;
                    }
                case (int)TemplateMatchModes.CCorrNormed:
                    {
                        if (max >= ccorrValue[similar])
                        {
                            return p;
                        }
                        break;
                    }
                default:
                    break;
            }
            return null;
        }

        public static bool IsSimilarImage(System.Drawing.Bitmap originImage, System.Drawing.Bitmap newImage, int scanWidth = 0, int scanHeight = 0, float maxRate = 0.2f)
        {
            if (originImage == null || newImage == null || originImage.Size != newImage.Size)
            {
                return false;
            }
            if (scanWidth == 0)
            {
                scanWidth = originImage.Width;
            }
            if (scanHeight == 0)
            {
                scanHeight = originImage.Height;
            }
            var notSameCount = 0;
            for (var i = 0; i < originImage.Width; i++)
            {
                for (var j = 0; j < originImage.Height; j++)
                {
                    var colorOrigin = originImage.GetPixel(i, j);
                    var colorNew = newImage.GetPixel(i, j);
                    if (colorOrigin.R != colorNew.R)
                    {
                        if (colorOrigin.G != colorNew.G)
                        {
                            if (colorOrigin.B != colorNew.B)
                            {
                                notSameCount++;
                            }
                        }
                    }
                }
            }
            var rate = notSameCount / originImage.Width * originImage.Height;
            System.Diagnostics.Debug.WriteLine("样本/总数：{0}/{1}，百分比：{2}", notSameCount, originImage.Width * originImage.Height, rate);
            if (rate > maxRate)
            {
                return false;
            }
            return true;
        }
    }
}
